#include "ColorBar.h"

#include <algorithm>

#include <algorithm/shared/utils/Vec3.h>
#include <utils/Format.h>
#include <utils/Print.h>


using namespace solar;

ColorBar::ColorBar(float min_value, float max_value) : min_value_(min_value), max_value_(max_value)
{
    setColor();
}

void ColorBar::test()
{
    solar::println("test color");
    solar::println(solar::format("{} {}", factors_.size(), colors_.size()));
    // for(int i=0;i<colors_.size();i++)
    // {
    //     std::cout << factors_[i] <<" color = "<<+colors_[i][0]
    //     <<","<<+colors_[i][1]<<","<<+colors_[i][3] << std::endl;
    // }
}

void ColorBar::setMinMax(float min_value, float max_value)
{
    min_value_ = min_value;
    max_value_ = max_value;
}
auto ColorBar::getMin() -> float { return min_value_; }
auto ColorBar::getMax() -> float { return max_value_; }

void ColorBar::setColor()
{
    solar::println("set color");
    int num = 8;
    int i = 0;
    rgb8_pixel_t color;
    while (i <= num)
    {
        // colors_value_.push_back((max_ - min_) / num * i)
        if (i == 0 || i == 8)
        {
            if (i == 0)
            {
                color = rgb8_pixel_t(0, 0, 0.5 * 255);
            }
            else
            {
                color = rgb8_pixel_t(0.5 * 255, 0, 0);
            }
            float factor = static_cast<float>(i) / num;
            colors_.emplace_back(color);
            factors_.emplace_back(factor);
            i++;
        }
        else
        {
            float r = i == 5 || i == 7 ? 1.0 : 0.0;
            float g = i == 3 || i == 5 ? 1.0 : 0.0;
            float b = i == 1 || i == 3 ? 1.0 : 0.0;
            color = rgb8_pixel_t(r * 255, g * 255, b * 255);
            float factor = static_cast<float>(i) / num;
            colors_.emplace_back(color);
            factors_.emplace_back(factor);
            if (i == 7)
            {
                i++;
            }
            else
            {
                i += 2;
            }
        }
    }
}

auto ColorBar::getColorAtValue(float value) -> rgb8_pixel_t
{
    float factor = getFactor(value);
    auto ret = getColorAtFactor(factor);

    return ret;
}
auto ColorBar::getColorAtValue(float value, float min_value, float max_value) -> rgb8_pixel_t
{
    float factor = (value - min_value) / (max_value - min_value);
    auto ret = getColorAtFactor(factor);

    return ret;
}
auto ColorBar::getColorAtFactor(float factor) -> rgb8_pixel_t
{
    int lower_index = std::lower_bound(factors_.begin(), factors_.end(), factor) - factors_.begin();
    int upper_index = std::upper_bound(factors_.begin(), factors_.end(), factor) - factors_.begin();

    if (lower_index < upper_index) // 表示有一个等于factor
    {
        int index = lower_index;
        return colors_[index];
    }
    int left_index = lower_index - 1, right_index = lower_index;
    float coeff = (factor - factors_[left_index]) / (factors_[right_index] - factors_[left_index]);
    auto left_color = colors_[left_index];
    auto right_color = colors_[right_index];

    rgb8_pixel_t ret;
    ret[0] = left_color[0] + (right_color[0] - left_color[0]) * coeff;
    ret[1] = left_color[1] + (right_color[1] - left_color[1]) * coeff;
    ret[2] = left_color[2] + (right_color[2] - left_color[2]) * coeff;

    return ret;
}
auto ColorBar::getRedComponentAtValue(float value) -> int { return getColorAtValue(value)[0]; }
auto ColorBar::getGreenComponentAtValue(float value) -> int { return getColorAtValue(value)[1]; }
auto ColorBar::getBlueComponentAtValue(float value) -> int { return getColorAtValue(value)[2]; }

auto ColorBar::getFactor(float value) -> float
{
    return std::clamp(value / (max_value_ - min_value_), 0.0F, 1.0F);
}
